package main

import "fmt"

//变量总是存在于内存中
/*
1、直接声明
var person Person
2、方式2： {}
var person Person = Person{}
3、方式3： &
var person *Person = new(Person)
4、方式4： {}
var person *Person = &Person{}

5、说明
(1)第3种和第4种方式返回的是结构体指针
(2)结构体指针访问字段的标准方式应该是：(*结构体指针).字段名，比如(*person).Name="tom"
(3)但go做了一个简化，也支持 结构体指针.字段名，比如person.Name="tom"。
更加符合程序员的使用习惯，go编译器底层对person.Name做了转化(*person).Name
*/
type Person struct {
	Name string
	Age  int
}

func main() {
	//方式2
	p2 := Person{"mary", 20}
	fmt.Println(p2)

	//方式3
	var p3 *Person = new(Person)
	//(*p3).Name = "smith"也可以这样写p3.Name="smith"
	//原因：go的设计者为了程序员使用方便，底层会对p3.Name="smith"进行处理，会给p3加上取值运算(*p3).Name = "smith"
	(*p3).Name = "smith"
	p3.Name = "jack"
	(*p3).Age = 30
	fmt.Println(*p3)

	//方式4
	//下面的语句也可以直接给字符赋值
	//var person *Person = &Person{"mary",60}
	var person *Person = &Person{}
	//因为person是一个指针，因此标准的访问字段的方法是(*person).Name="scott"
	//go的设计者为了程序员使用方便，底层会对person.Name="scott"进行处理，会给person加上取值运算(*person).Name = "smith"
	person.Name = "scott"
	person.Age = 13
	fmt.Println(*person)
}
